package com.myaihui.service.impl;

import com.myaihui.domain.Content;
import com.myaihui.foundation.model.Pager;
import com.myaihui.foundation.query.ContentQuery;
import com.myaihui.repository.ContentRepostory;
import com.myaihui.service.ContentService;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by sun on 2018/6/4.
 *
 * @author sunfuchang03@126.com
 * @version 1.0
 * @since 1.0
 */
@Data
@Service
public class ContentServiceImpl implements ContentService {
    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     *
     * Static fields/constants/initializer
     *
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */

    private static Logger log = LoggerFactory.getLogger(ContentServiceImpl.class);

    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     *
     * Instance fields
     *
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */

    @Autowired
    private ContentRepostory contentRepostory;

    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     *
     * Constructors
     *
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */



    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     *
     * Public Methods
     *
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */

    @Override
    public Content add(Content content) {
        Assert.notNull(content, "content must not be null.");
        return contentRepostory.save(content);
    }

    @Override
    public void delete(String id) {
        Assert.hasLength(id, "id must not be empty.");
        contentRepostory.delete(id);
    }

    @Override
    public Content update(Content content) {
        Assert.notNull(content, "content must not be null.");
        return contentRepostory.save(content);
    }

    @Override
    public Content get(String id) {
        Assert.hasLength(id, "id must not be empty.");
        return contentRepostory.getOne(id);
    }

    @Override
    public Pager<Content> pageQuery(ContentQuery query) {
        Assert.notNull(query, "quer must not be null");
        Specification<Content> specification = (root, criteriaQuery, cb) -> {
            List<Predicate> predicates = new ArrayList<>();

            String title = query.getTitle();
            Integer state = query.getState();
            Date createStartTime = query.getCreateStartTime();
            Date createEndTime = query.getCreateEndTime();
            String subjectId = query.getSubjectId();
            if (StringUtils.hasLength(title)) {
                predicates.add(cb.and(cb.like(root.get("title"), "%" + title + "%")));
            }
            if (state != null) {
                predicates.add(cb.and(cb.equal(root.get("state"), state)));
            }
            if (createStartTime != null) {
                predicates.add(cb.greaterThanOrEqualTo(root.get("created"), createStartTime));
            }
            if (createEndTime != null) {
                predicates.add(cb.lessThanOrEqualTo(root.get("created"), createEndTime));
            }
            if (StringUtils.hasLength(subjectId)) {
                predicates.add(cb.equal(root.get("createUserPlatform"), subjectId));
            }
            criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));
            criteriaQuery.orderBy(cb.desc(root.get("created")));
            return criteriaQuery.getRestriction();
        };
        Pageable pageable = new PageRequest(query.getiDisplayStart(), query.getiDisplayLength());
        Page<Content> page = contentRepostory.findAll(specification, pageable);
        return new Pager<>(page, query.getsEcho(), page.getContent());
    }

    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     *
     * Private Methods
     *
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */


}